package de.fhtrier.gdw2.ships.menu;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

import de.fhtrier.gdw2.ships.game.Constants;
import de.fhtrier.gdw2.ships.menu.pages.MenuPageRoot;
import de.fhtrier.gdw2.ships.utils.AssetLoader;

import java.util.Random;

/**
 * Menu state
 * 
 * @author Lusito
 * @author Kevin Korte
 */
public class MenuManager
	{
		MenuPage rootPage;
		MenuPage currentPage;
		/** The key repeat interval */
		private static final int INITIAL_KEY_REPEAT_INTERVAL = 400;
		/** The key repeat interval */
		private static final int KEY_REPEAT_INTERVAL = 50;
		/** The last key pressed */
		private int lastKey = -1;
		/** The last character pressed */
		private char lastChar = 0;
		/** The time since last key repeat */
		private long repeatTimer;
		/** The input we're responding to */
		protected Input input;

		float xOffset = 0;
		float yOffset = 0;

		private Color screenDarken = new Color(0, 0, 0, 0.75f);

		protected Image screen;
		long lastBrickRefresh;
		private Random rand = new Random();
		char[] randomBricks =
			{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
		// A, B, AB, D, AD
		char[][] data = new char[Constants.WINDOW_PIXI_WIDTH][Constants.WINDOW_PIXI_HEIGHT];
		boolean hasFreeBricks;

		public enum Type
		{
			MAINMENU, INGAME
		};

		public MenuManager(final GameContainer container,
				final StateBasedGame game, Type type) throws SlickException
			{
				input = container.getInput();
				switch (type)
					{
					case MAINMENU:
						rootPage = currentPage = new MenuPageRoot(container,
								game, this, false);
						break;
					case INGAME:
						rootPage = currentPage = new MenuPageRoot(container,
								game, this, true);
						break;
					}

				for (int x = 0; x < data.length; x++)
					{
						for (int y = 0; y < data[0].length; y++)
							{
								data[x][y] = 's';
							}
					}
				screen = new Image("res/menu/screen.png");
			}

		public void render(GameContainer container, StateBasedGame game,
				Graphics g) throws SlickException
			{
				if (currentPage != null)
					{
						g.setColor(screenDarken);
						g.fillRect(0, 0, container.getWidth(),
								container.getHeight());
						g.setColor(Color.white);
						drawBricks();

						int y = (game.getContainer().getHeight() - screen
								.getHeight()) / 2;
						screen.draw(0, y, game.getContainer().getWidth(),
								screen.getHeight());
						currentPage.render(g);
					}
			}

		private void drawBricks()
			{
				/**
				 * Wird noch ersetzt durch eine Methode, die ein Spaceship rendert, das über den Bildschirm fliegt
				*/
				
				// draw the bricks
				hasFreeBricks = false;
				for (int x = 0; x < data.length; x++)
					{
						for (int y = 0; y < data[0].length; y++)
							{

								if (data[x][y] == 's')
									{
										hasFreeBricks = true;
									} else
									{
										String s;
										switch (data[x][y])
											{
											case 'A':
											case 'B':
											case 'D':
												s = "mod_weap_" + data[x][y];
												break;
											case 'E':
												s = "mod_weap_AD";
												break;
											case 'C':
												s = "mod_weap_AB";
												break;
											case 'F':
												s = "mod_ener_A";
												break;
											case 'G':
												s = "mod_ener_B";
												break;
											case 'H':
												s = "mod_ener_C";
												break;
											case 'I':
												s = "mod_ener_D";
												break;
											default:
												s = "mod_central";
											}

										Image mod = AssetLoader.getInstance()
												.getImage(s);
										mod.draw(x * Constants.COMPONENTSIZE, y
												* Constants.COMPONENTSIZE);
									}
								
							}
					}

				// update the random bricks
				long currentTime = System.currentTimeMillis();
				if (currentTime - lastBrickRefresh > 40)
					{
						lastBrickRefresh = currentTime;
						int x = rand.nextInt(data.length);
						int y = rand.nextInt(data[0].length);
						if (data[x][y] == 's' || !hasFreeBricks)
							data[x][y] = randomBricks[rand
									.nextInt(randomBricks.length)];
						else
							{
								boolean found = false;
								// free bricks left, try to find them
								for (int i = 0; i < 40; i++)
									{
										x = rand.nextInt(data.length);
										y = rand.nextInt(data[0].length);
										if (data[x][y] == 's')
											{
												data[x][y] = randomBricks[rand
														.nextInt(randomBricks.length)];

												found = true;
												break;
											}
									}
								// random failed, get the first
								if (!found)
									{
										for (x = 0; x < data.length; x++)
											{
												for (y = 0; y < data[0].length; y++)
													{
														if (data[x][y] == 's')
															{
																data[x][y] = randomBricks[rand
																		.nextInt(randomBricks.length)];
																break;
															}
													}
											}
									}
							}

						// remove full lines
						for (y = 0; y < data[0].length; y++)
							{
								boolean fullLine = true;
								for (x = 1; x < data.length; x++)
									{
										if (data[x][y] == 's')
											{
												fullLine = false;
												break;
											}
									}
								if (fullLine)
									{
										for (x = 0; x < data.length; x++)
											{
												data[x][y] = 's';
											}
									}
							}
					}
			}

		public void update(GameContainer container, StateBasedGame game,
				int delta) throws SlickException
			{
				if (lastKey != -1 && currentPage != null)
					{
						if (input.isKeyDown(lastKey))
							{
								if (repeatTimer < System.currentTimeMillis())
									{
										repeatTimer = System
												.currentTimeMillis()
												+ KEY_REPEAT_INTERVAL;
										currentPage.keyPressed(lastKey,
												lastChar, true);
									}
							} else
							{
								lastKey = -1;
							}
					}
			}

		public MenuPage getCurrentPage()
			{
				return currentPage;
			}

		public void setPage(MenuPage page)
			{
				if (page == null)
					{
						// Transition transitionOut = new
						// FadeOutTransition(Color.black, 500);
						// Transition transitionIn = new
						// FadeInTransition(Color.black, 500);
						// game.enterState(SlickTestGameState.GAMEPLAYSTATE,
						// transitionOut, transitionIn);
					} else
					{
						page.activate();
					}
				currentPage = page;
			}

		public void activate()
			{
				setPage(rootPage);
			}

		public boolean keyReleased(int key, char c)
			{
				if (key == Input.KEY_ESCAPE && currentPage == rootPage)
					return false;

				if (currentPage != null)
					currentPage.keyReleased(key, c);
				return true;
			}

		public void keyPressed(int key, char c)
			{
				if (currentPage != null)
					{
						if (lastKey != key)
							{
								lastKey = key;
								repeatTimer = System.currentTimeMillis()
										+ INITIAL_KEY_REPEAT_INTERVAL;
							} else
							{
								repeatTimer = System.currentTimeMillis()
										+ KEY_REPEAT_INTERVAL;
							}
						lastChar = c;

						currentPage.keyPressed(key, c, false);
					}
			}

		public void mouseMoved(int oldx, int oldy, int newx, int newy)
			{
				if (currentPage != null)
					{
						oldx -= xOffset;
						oldy -= yOffset;
						newx -= xOffset;
						newy -= yOffset;
						currentPage.mouseMoved(oldx, oldy, newx, newy);
					}
			}

		public void mouseDragged(int oldx, int oldy, int newx, int newy)
			{
				if (currentPage != null)
					{
						oldx -= xOffset;
						oldy -= yOffset;
						newx -= xOffset;
						newy -= yOffset;
						currentPage.mouseDragged(oldx, oldy, newx, newy);
					}
			}

		public void mouseReleased(int button, int x, int y)
			{
				if (currentPage != null)
					{
						x -= xOffset;
						y -= yOffset;
						currentPage.mouseReleased(button, x, y);
					}
			}

		public void mousePressed(int button, int x, int y)
			{
				if (currentPage != null)
					{
						x -= xOffset;
						y -= yOffset;
						currentPage.mousePressed(button, x, y);
					}
			}

		public void mouseWheelMoved(int newValue)
			{
				if (currentPage != null)
					currentPage.mouseWheelMoved(newValue);
			}
	}